package com.ticket.sass.admin.controller;


import com.alibaba.excel.EasyExcel;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.ticket.sass.admin.annotation.AuthIgnore;
import com.ticket.sass.admin.annotation.Loggable;
import com.ticket.sass.admin.annotation.Module;
import com.ticket.sass.admin.business.FileUpLoadBusiness;
import com.ticket.sass.admin.business.OrderTicketBusiness;
import com.ticket.sass.admin.dto.input.order.OrderTicketListInput;
import com.ticket.sass.admin.dto.input.order.TicketRefundInput;
import com.ticket.sass.admin.dto.output.order.CouponOutput;
import com.ticket.sass.admin.dto.output.order.OrderDataModel;
import com.ticket.sass.admin.dto.output.order.OrderTicketListOutput;
import com.ticket.sass.admin.dto.output.order.TicketOutput;
import com.ticket.sass.admin.dto.output.order.export.OrderTicketListExport;
import com.ticket.sass.admin.handler.IdentityInput;
import com.ticket.sass.admin.manager.ThreadLocalIdInputHolderManager;
import com.ticket.sass.admin.model.ResultModel;
import com.ticket.sass.common.exception.enums.ErrorCode;
import com.ticket.sass.common.exception.exception.BadRequestException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author ywb
 * @since 2024-03-07
 */
@RestController
@AllArgsConstructor
@ApiSupport(order = 17)
@Api(tags = {"票务订单数据-模块"})
@RequestMapping("/ticket-orders")
public class OrderTicketController {
    final OrderTicketBusiness business;
    final FileUpLoadBusiness fileUpLoadBusiness;
    
    @ApiOperation("列表")
    @GetMapping
    public ResultModel<OrderDataModel<OrderTicketListOutput>> list(
        @Valid OrderTicketListInput input
    ) {
        return ResultModel.success(
            business.list(input)
        );
    }
    
    
    @ApiOperation("退单")
    @PostMapping("/refund")
    @Loggable(module = Module.ORDER, desc = "票务订单退单")
    public ResultModel<String> refund(
        @RequestBody @Valid TicketRefundInput input
    ) {
        business.refund(input);
        return ResultModel.success();
    }
    
    @AuthIgnore
    @ApiOperation("导出")
    @GetMapping("/export")
    public void exportCouponCodes(
        @Valid OrderTicketListInput input,
        HttpServletResponse response,
        @Valid Long cinemaId,
        @Valid String token
    ) {
        if (Objects.isNull(cinemaId)){
            throw new BadRequestException(
                ErrorCode.BUSINESS_ERROR,
                "影院ID不能为空"
            );
        }
        if (!fileUpLoadBusiness.existExportToken(token, "order-ticket")) {
            throw new BadRequestException(
                ErrorCode.BUSINESS_ERROR,
                "token过期"
            );
        }
        
        // 设置请求参数
        input.setPageNum(1);
        input.setPageSize(1000);
        
        IdentityInput value = ThreadLocalIdInputHolderManager.getValue();
        value.setCinemaId(cinemaId);
        
        ThreadLocalIdInputHolderManager.setValue(value);
        
        // 调用业务逻辑获取数据
        List<OrderTicketListOutput> list = business.list(input).getList();
        
        List<OrderTicketListExport> exports = list.stream().map(OrderTicketController::convert).collect(Collectors.toList());
        
        
        // 设置响应头
        // 设置响应头，指定Content-Type和文件名
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(String.valueOf(System.currentTimeMillis()), StandardCharsets.UTF_8);
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
        // 写入数据到Excel文件
        try (OutputStream outputStream = response.getOutputStream()) {
            EasyExcel.write(outputStream, OrderTicketListExport.class).sheet("票务订单").doWrite(exports);
        } catch (Exception e) {
            // 处理异常
            e.printStackTrace();
            throw new BadRequestException(
                ErrorCode.BUSINESS_ERROR,
                "导出失败"
            );
        }
    }
    
    
    public static OrderTicketListExport convert(OrderTicketListOutput output) {
        OrderTicketListExport export = new OrderTicketListExport();
        export.setOrderNo(output.getOrderNo());
        export.setCellphone(output.getCellphone());
        
        // 假设 takeCode 是单个值，取第一个
        export.setTakeCode(output.getTakeCode().values().stream().findFirst().orElse(null));
        StringJoiner str = new StringJoiner(System.lineSeparator());
        if (output.getSession() != null){
            str.add(output.getSession().getFilmName());
            str.add(output.getSession().getHallName());
            str.add(output.getSession().getFilmLang());
            str.add(output.getSession().getFilmVersion());
            str.add(output.getSession().getStartTime().toString());
            export.setSessionInfo(str.toString());
        }

        
        // 票信息
        str = new StringJoiner(System.lineSeparator());
        for (TicketOutput ticket : output.getTickets()) {
            String ticketInfo = "座位 " + ticket.getSeat() + "\t" +
                "  票价 " + ticket.getPrice() + "\t" +
                "  服务费 " + ticket.getServiceFee() + "\n";
            str.add(ticketInfo);
        }
        export.setTicketInfo(str.toString());
        
        // 优惠信息
        StringBuilder couponInfo = new StringBuilder();
        for (CouponOutput coupon : output.getCoupons()) {
            couponInfo.append(coupon.getName()).append(" ")
                .append(coupon.getDiscountAmount()).append("\n");
        }
        export.setCouponInfo(couponInfo.toString());
        
        // 票价方案
        export.setPriceSchemes(output.getPriceSchemes() != null ? output.getPriceSchemes().getName() + "/" + output.getPriceSchemes().getPrice() : "暂无票价方案");
        
        // 金额
        export.setPayAmount(output.getPayPrice().toString());
        export.setShowAmount(output.getTicketPrice().toString());
        
        // 支付类型
        String payType = switch (output.getPayType()) {
            case 1 -> "微信支付";
            case 2 -> "支付宝支付";
            case 3 -> "会员卡支付";
            default -> "未知支付方式";
        };
        export.setPayType(payType);
        
        export.setCreateAt(output.getCreatedAt().toString().replace("T", " "));
        export.setPayDatetime(output.getPayTime().toString().replace("T", " "));
        
        // 备注
        export.setRemark(output.getRemark());
        
        return export;
    }
    
}
